package utilities;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import main.proyecto_pei.R;
import utilities.service.InsertarLlamadas;
import utilities.service.InsertarSms;
import main.proyecto_pei.MainActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class MyService extends Service {
	private static final String TAG = "PEI";
	
	final int RECIBIDOS = 1;
	final int ENVIADOS = 2;
	
	private Timer timer = new Timer();
	private static final long UPDATE_INTERVAL = 2000;
	private static final long UPDATE_INTERVAL_PRESUP = 86400;
	
	private int _idUltimoSms = -1;
	
	Preferencias pref;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		Log.d(TAG, "onCreate");
		pref = new Preferencias(MyService.this);
		leerPrimerSms();
		monotoriarSms();
		monotoriarPresup();
	}

	@Override
	public void onDestroy() {
		Log.d(TAG, "Destruido");
	}
	
	@Override
	public void onStart(Intent intent, int startid) {
		//Toast.makeText(this, "Servicio Iniciado", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onStart");
		//Clase para estar leyendo el estado de las llamadas
		IncomingCallReciever ic = new IncomingCallReciever();
        ic.onReceive(this, new Intent(MyService.this,MyService.class));

	}
	
	/****************************************************************************************
	****************************************************************************************
	 * MONITORIAR SMS
	 ****************************************************************************************
	 ****************************************************************************************/
	private void monotoriarSms(){
		timer.scheduleAtFixedRate(new TimerTask() {
				@Override
				public void run() {
					int _id;
					try{
						
						long fec;
						Date dPresup,dActual;
						//Si la fecha actual es menor a la del presupuesto, no hacemos nada
						if(pref.getPref(Preferencias.EXISTE_PRESUPUESTO, Preferencias.NO).equals(Preferencias.SI)){
							fec = Long.parseLong(pref.getPref(Preferencias.FECHA_INI_PRESUP, "-1"));
							dPresup = new Date(fec);
							dActual = new Date();
							if(dActual.before(dPresup)) return;
						}
						
						Uri uriSMSURI = Uri.parse("content://sms/");
					    Cursor cur = getContentResolver().query(uriSMSURI, null, "TYPE = "+ENVIADOS, null,"date DESC");
					    if(cur.moveToNext()) {
					    	_id = cur.getInt(cur.getColumnIndex("_id"));
					    	if(_id != _idUltimoSms){
					    		
					    		try {Thread.sleep(1500);
				                } catch (InterruptedException e) {  e.printStackTrace();    }
					    		
					    		new InsertarSms(MyService.this);
					    		
					    		if(verificarMontoPresup()){//Si retorna TRUE es porque ya sobrepaso el presupuesto	            		
				            		if(pref.getPref(Preferencias.NOTIFICAR_LIM_PRESUP, Preferencias.NO).equals(Preferencias.SI))
				            			lanzarNotificacion("Presupuesto Sobrepasado");
				            		else
				            			if(pref.getPref(Preferencias.NOTIFICAR_ENVIAR_SMS, Preferencias.NO).equals(Preferencias.SI))
						            		lanzarNotificacion("Mensaje enviado");
				            	}else{
				            		if(pref.getPref(Preferencias.NOTIFICAR_ENVIAR_SMS, Preferencias.NO).equals(Preferencias.SI))
					            		lanzarNotificacion("Mensaje enviado");
				            	}
					    		_idUltimoSms = _id;
					    	}
					    	
					     }
					}catch (Exception e) {
						e.printStackTrace();
//						Log.i(TAG, e.getMessage());
					}
				}
			}, 0, UPDATE_INTERVAL);
	}
	
	//Leemos el ultimo sms enviado para luego, estar comparando con este ultimo id. Si el id que recuperemos
	//es diferente a este _idUltimoSms es porque hay un nuevo mensaje en el buzon de salida
	private void leerPrimerSms(){
		try{
			Uri uriSMSURI = Uri.parse("content://sms/");
		    Cursor cur = getContentResolver().query(uriSMSURI, null, "TYPE = "+ENVIADOS, null,"date DESC");
		    if(cur.moveToNext()) {
		    	_idUltimoSms = cur.getInt(cur.getColumnIndex("_id")); 
		    	
		     }
		}catch (Exception e) {
			e.printStackTrace();
//			Log.i(TAG, e.getMessage());
		}
	}
	
	
	
	
	
	/****************************************************************************************
	 * ****************************************************************************************
	 * MONITORIAR LLAMADAS
	 * ****************************************************************************************
	 ****************************************************************************************/
	public class IncomingCallReciever extends BroadcastReceiver {

//		private Context mContext;
//		private Intent mIntent;
		private boolean isPhoneCalling = false;
//		private String TAG="PEI";

		@Override
		public void onReceive(Context context, Intent intent) {
//			mContext = context;
//			mIntent = intent;
			TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			int events = PhoneStateListener.LISTEN_CALL_STATE;
			tm.listen(phoneStateListener, events);
		}

		private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
			
			@Override
		    public void onCallStateChanged(int state, String incomingNumber) {

		        if (TelephonyManager.CALL_STATE_RINGING == state) {
		            // phone ringing
//		            Log.i(TAG, "RINGING, number: " + incomingNumber);
		        }

		        if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
		            // active
//		            Log.i(TAG, "OFFHOOK");

		            isPhoneCalling = true;
		        }

		        if (TelephonyManager.CALL_STATE_IDLE == state) {
		            // run when class initial and phone call ended,
		            // need detect flag from CALL_STATE_OFFHOOK
//		            Log.i(TAG, "IDLE");

		            if (isPhoneCalling) {
		            	
		            	long fec;
		        		Date dPresup,dActual;
		        		//Si la fecha actual es menor a la del presupuesto, no hacemos nada
		        		if(pref.getPref(Preferencias.EXISTE_PRESUPUESTO, Preferencias.NO).equals(Preferencias.SI)){
		        			fec = Long.parseLong(pref.getPref(Preferencias.FECHA_INI_PRESUP, "-1"));
		        			dPresup = new Date(fec);
		        			dActual = new Date();
		        			if(dActual.before(dPresup)) return;
		        		}
		            	
		            	try {Thread.sleep(1500);
		                } catch (InterruptedException e) {  e.printStackTrace();    }
		            	
		            	new InsertarLlamadas(MyService.this);
		            	if(verificarMontoPresup()){//Si retorna TRUE es porque ya sobrepaso el presupuesto	            		
		            		if(pref.getPref(Preferencias.NOTIFICAR_LIM_PRESUP, Preferencias.NO).equals(Preferencias.SI))
		            			lanzarNotificacion("Presupuesto Sobrepasado");
		            		else
		            			if(pref.getPref(Preferencias.NOTIFICAR_TERMINA_LLAMADA, Preferencias.NO).equals(Preferencias.SI))
			            			lanzarNotificacion("Termino la llamada");
		            	}else{
		            		if(pref.getPref(Preferencias.NOTIFICAR_TERMINA_LLAMADA, Preferencias.NO).equals(Preferencias.SI))
		            			lanzarNotificacion("Termino la llamada");
		            	}
//		                Log.i(TAG, "TERMINO LA LLAMADA =D");

//		                //restart call application
//		                Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
//		                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
//		                        | Intent.FLAG_ACTIVITY_CLEAR_TOP
//		                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
//		                startActivity(i);

		                isPhoneCalling = false;
		            }

		        }


		}
			
		};
	}
	
	
	
	/****************************************************************************************
	 * ****************************************************************************************
	 * MONITORIAR PRESUPUESTO
	 * ****************************************************************************************
	 ****************************************************************************************/
	private void monotoriarPresup(){
		//esta accion se ejecutara una vez al día (cada 86400seg)
		timer.scheduleAtFixedRate(new TimerTask() {
				@Override
				public void run() {
					if(pref.getPref(Preferencias.EXISTE_PRESUPUESTO, Preferencias.NO).equals(Preferencias.NO)) return;
					BDSQLiteHelper usdbh = new BDSQLiteHelper(MyService.this, "DB_PEI", null, 1);
					SQLiteDatabase db = null;
					int dias=0;
					//aumentamos un dia
					int contadorDias = Integer.parseInt(pref.getPref(Preferencias.CONTADOR_DIAS_PRESUP, "0"));
					contadorDias++;					
					//float montoTotal = Float.parseFloat(pref.getPref(Preferencias.CONSUMO_TOTAL, "0"));
					try{
						db = usdbh.getReadableDatabase();
						Cursor c_plan = db.query("PEI_PRESUPUESTO", new String[] {"CANTIDAD_DIAS"}, null, null, null, null, null);
						if(c_plan.moveToFirst()){
							dias = c_plan.getInt(0);
						}
						//Verificamos si ya pasaron los N dias para reniciar
						if(contadorDias>dias){
							pref.setPref(Preferencias.CONSUMO_TOTAL, "0.0");
				    	    pref.setPref(Preferencias.MINUTOS_CONSUMIDOS, "0");
				    	    pref.setPref(Preferencias.MENSAJES_ENVIADOS, "0");
				    	    pref.setPref(Preferencias.CONTADOR_DIAS_PRESUP, "0");
							lanzarNotificacion("Presupuesto Reiniciado");
						}
					}catch(Exception e){
						e.printStackTrace();
					}
					finally{
						db.close();
					}
					pref.setPref(Preferencias.CONTADOR_DIAS_PRESUP, contadorDias+"");
				}
			}, 0, UPDATE_INTERVAL_PRESUP);
	}
	
	
	
	
	
	
	/****************************************************************************************
	 * ****************************************************************************************
	 * LANZAR NOTIFICACION
	 * ****************************************************************************************
	 ****************************************************************************************/
	
	void lanzarNotificacion(String num){
		String ns = Context.NOTIFICATION_SERVICE;
		NotificationManager notManager = (NotificationManager) getSystemService(ns);
		AlertaData ad = getAlertaActiva();
		if(ad==null) return;//Si es null es porque no hay alerta activa
		
		//Configuramos la notificacion
		int icono = R.drawable.money;
		CharSequence textoEstado = "Proyecto PEI";
		long hora = System.currentTimeMillis();

		Notification notif = new Notification(icono, textoEstado, hora);
		
		//Configuramos el Intent
		Context contexto = MyService.this;
		CharSequence titulo = num;
		CharSequence descripcion = ad.getMensaje();
				
		Intent notIntent = new Intent(contexto,MainActivity.class);
    	PendingIntent contIntent = PendingIntent.getActivity(contexto, 0, notIntent, 0);

    	notif.setLatestEventInfo(contexto, titulo, descripcion, contIntent);
    	
		notif.flags |= Notification.FLAG_AUTO_CANCEL;
		//Añadir sonido, vibración y luces
		if(ad.getSonido()!=null)
			if(ad.getSonido()==-1) notif.defaults |= Notification.DEFAULT_SOUND;
			else notif.sound = Uri.parse("android.resource://" + getPackageName() + ad.getSonido());
		
		if(ad.isVibrar()){
			notif.defaults |= Notification.DEFAULT_VIBRATE;
			notif.defaults |= Notification.DEFAULT_LIGHTS;
		}
		
		notManager.notify(1, notif);
//		finish();
		}
	
	 private AlertaData getAlertaActiva() {
			BDSQLiteHelper usdbh = new BDSQLiteHelper(this, "DB_PEI", null, 1);
			SQLiteDatabase db = null;
			AlertaData ad=null;
			try {
				db = usdbh.getReadableDatabase();
				Cursor c = db.query("PEI_ALERTA", new String[] {"ID_ALERTA,MENSAJE","SONIDO","VIBRAR"}, "IS_ACTIVO=?", new String[]{"1"}, null, null, null);
				if(c.moveToNext()){
					ad = new AlertaData(Integer.parseInt(c.getString(0)),
							c.getString(1),
							true,
							(Integer.parseInt(c.getString(2))),
							(Integer.parseInt(c.getString(3)) == 1));
				}
			} catch (Exception e) {
				e.printStackTrace();
				Log.i("ERROR CARGARALERTA", e.getMessage());
			}
			finally{
				db.close();
			}
			return ad;
		}
	
	 
	 /****************************************************************************************
		 * ****************************************************************************************
		 * VERIFICAR MONTO PRESUPUESTO
		 * ****************************************************************************************
		 ****************************************************************************************/
	 
	 boolean verificarMontoPresup(){
		 if(pref.getPref(Preferencias.EXISTE_PRESUPUESTO, Preferencias.NO).equals(Preferencias.NO)) return false;
			BDSQLiteHelper usdbh = new BDSQLiteHelper(MyService.this, "DB_PEI", null, 1);
			SQLiteDatabase db = null;
			float monto=0;
			float montoTotal = Float.parseFloat(pref.getPref(Preferencias.CONSUMO_TOTAL, "0"));
			try{
				db = usdbh.getReadableDatabase();
				Cursor c_plan = db.query("PEI_PRESUPUESTO", new String[] {"MONTO"}, null, null, null, null, null);
				if(c_plan.moveToFirst()){
					monto = Float.parseFloat(c_plan.getString(0));
				}
				//Verificamos si ya se sobrepaso el monto
				if(montoTotal>monto){
	            		return true;
				}
			}catch(Exception e){
				e.printStackTrace();
			}
			finally{
				db.close();
			}
			return false;
	 }
	
}